﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using SimplePoker.Main;

namespace SimplePoker.tests
{

    [TestClass]
    public class first_test
    {
        private AlwaysBetPlayer _Aggro1 = new AlwaysBetPlayer("Aggro_1");
        private AlwaysBetPlayer _Aggro2 = new AlwaysBetPlayer("Aggro_2");
        private AlwaysCallPlayer _AlwaysCall1 = new AlwaysCallPlayer("Always Call 1");
        private AlwaysCallPlayer _AlwaysCall2=  new AlwaysCallPlayer("Always Call 2");
        private BasicPlayer _BasicPlayer1 = new BasicPlayer("Basic 1");
        private AlwaysFoldPlayer _Stel1 = new AlwaysFoldPlayer("Stel");
              
        [TestMethod]
        public void always_raise_player_returns_raise_when_called()
        {
            var result = _Aggro1.GetAction();
            Assert.AreEqual<PlayerAction>(PlayerAction.BET, result);
        }

        [TestMethod]
        public void if_only_one_player_calls_round_should_not_have_ended()
        {
            var round = new Round(_AlwaysCall1, _Aggro1);

            round.DoNextAction();
            round.DoNextAction();

            Assert.IsFalse(round.HasEnded);
        }

        [TestMethod]
        public void pot_size_is_2_when_round_starts()
        {
            var round = new Round(_Aggro1,_AlwaysCall1);
            Assert.AreEqual<int>(2, round.PotSize);
        }

        [TestMethod]
        public void stel_always_folds()
        {
            Assert.AreEqual<PlayerAction>(PlayerAction.FOLD, _Stel1.GetAction());
        }

        [TestMethod]
        public void players_have_a_card_assigned_to_them_when_round_starts()
        {
            var round = new Round(_Stel1, _Aggro1);

            Assert.IsNotNull(_Stel1.Card);
            Assert.IsNotNull(_Aggro1.Card);
        }

        [TestMethod]
        public void if_a_player_folds_their_opponent_wins_the_pot()
        {
            var round = new Round(_Aggro1, _Stel1);

            round.DoNextAction();
            round.DoNextAction();

            Assert.AreEqual<int>(1001, _Aggro1.ChipCount);
        }
       
        [TestMethod]
        public void if_player_has_one_chip_left_they_are_forced_to_call()
        {
            var round = new Round(_Aggro1, _Aggro2);
            _Aggro1.ChipCount = 1;
            _Aggro2.ChipCount = 1;

            round.DoNextAction();
            round.DoNextAction();

            Assert.IsTrue(round.IsShowdown);
        }

        [TestMethod]
        public void a_tournament_ends_when_one_player_has_no_chips_left()
        {
            var tourney = new Tournament(_Aggro1, _Aggro2);
            _Aggro2.ChipCount = 0;
            Assert.IsTrue(tourney.HasEnded);
        }

        [TestMethod]
        public void a_tournament_is_not_over_if_both_players_have_chips_left()
        {
            var tourney = new Tournament(_Aggro2, _Aggro1);
            Assert.IsFalse(tourney.HasEnded);
        }
        
               
        [TestMethod]
        public void players_are_toggled_after_action()
        {
            var round = new Round(_Aggro1, _Stel1);

            Assert.AreEqual<string>(_Aggro1.Name, round.NextToAct.Name);
            round.DoNextAction();
            Assert.AreEqual<string>(_Stel1.Name, round.NextToAct.Name);
        }


        [TestMethod]
        public void a_tournament_finishes()
        {
            var tourney = new Tournament(_Aggro1, _Aggro2);

            var winner = tourney.GetWinner();

            Assert.IsTrue(tourney.HasEnded);
        }

        
        [TestMethod]
        public void two_aggro_players_get_all_in_round_ends_only_one_has_chips_left()
        {
            var round = new Round(_Aggro1, _Aggro2);

            while (!round.HasEnded)
            {
                round.DoNextAction();
            }

            var one_busto = (_Aggro1.ChipCount == 0 || _Aggro2.ChipCount == 0);

            Assert.IsTrue(one_busto);
        }
        

        [TestMethod]
        [ExpectedException(typeof(ArgumentException))]
        public void player_cannot_have_negative_chips()
        {
            _Aggro1.ChipCount = -1;
        }
          
        [TestMethod]
        public void a_call_after_a_bet_ends_the_hand()
        {
            var round = new Round(_Aggro1, _AlwaysCall1);

            round.DoNextAction();
            round.DoNextAction();

            Assert.IsTrue(round.IsShowdown);
            Assert.IsTrue(round.HasEnded);
        }
    }
}
